#include <iostream>
#include <string>

//This is a 2D version of tictactoe that will be a prequel to the 3d version
//TODO Generate Dynamic Win Detection Function. In other words, not need to spell out each win scenario.
//TODO Error Checking on Number entries for marker location.

using namespace std;

bool GridLookup(int KeypadNumber,char PlayerSymbol);
int PlayerWinPossibilities(int x);

int turns=0;
int win=0;
char Grid[3][3];
string PlayerOne, PlayerTwo;

void GridDisplay()//Function that displays the Grid as it appears updating each player's position.
{
    cout << "+-----+  +-----+" << endl;
    cout << "|" <<Grid[0][0]<< "|" << Grid[0][1] << "|" << Grid[0][2]<< "|  |7|8|9|" << endl;
    cout << "+-+-+-+  +-+-+-+" << endl;
    cout << "|" <<Grid[1][0]<< "|" << Grid[1][1] << "|" << Grid[1][2]<< "|  |4|5|6|" << endl;
    cout << "+-+-+-+  +-+-+-+" << endl;
    cout << "|" <<Grid[2][0]<< "|" << Grid[2][1] << "|" << Grid[2][2]<< "|  |1|2|3|" << endl;
    cout << "+-----+  +-----+" << endl;
}

void Introduction()//Function that Introduces the game, and explains how to place their marker to the players.
{
        char instructions;
        do
        {
            cout << "Would you like instructions?"<<endl;
            cout << "(Y)es, (N)o."<< endl;
            cin >> instructions;
            if (instructions=='n'||instructions=='N')
                {
                    break;
                }
            else if (instructions=='y'||instructions=='Y')
                {	
					system("cls");
					cout << "On your turn you will enter in one of the" << endl;
					cout << "numbers corresponding to the location you" << endl;
					cout << "would like to place your marker. " << endl;
					cout << endl;
					cout << "Look down on your keypad on your keyboard." << endl;
					cout << "Basically if you divided your keypad into" << endl;
					cout << "a grid, you would press the number that is" << endl;
					cout << "in the location you would like to place "   << endl;
					cout << "your marker." << endl;
					cout << "Like so:" << endl;
					GridDisplay();
                }
			else 
				{
					cout << "Invalid entry." << endl;
				}
        }
        while (instructions != 'Y'||instructions != 'y');
}

string PlayerNames(int x)
{
    char correct;
    string player,name;

    if (x == 1)
        player="One";
    else if (x == 2)
        player="Two";
	else
		cout << "Invalid entry" << endl;
    do
    {
        cout <<"Player "<<player<<" please enter your name."<< endl;
        cin >> name;
        cout << "You entered |"<< name << "| is this correct?"<< endl;
        cout << "(Y)es, (N)o. "<< endl;
        cin >> correct;
        if (correct=='y')
            correct='Y';
    }
    while (correct!='Y');

    return (name);
}

bool SquareOpen(int x, int y)
{
    if (Grid[x][y]=='X'||Grid[x][y]=='O')
        return false;
    else
        return true;
}

void PlayerTurn()//What to do on the first player's turn.
{
    int x,y,Choice=1;
    char Symbol;
    do
    {
		system("cls");
        if (turns%2==0)
        {
            Symbol='X';
            cout << "----------------------------------"<< endl;
            cout << PlayerOne << "'s turn." << endl;
            cout << "----------------------------------"<< endl;
        }
        else
        {
            Symbol='O';
            cout << "----------------------------------"<< endl;
            cout << PlayerTwo << "'s turn." << endl;
            cout << "----------------------------------"<< endl;
        }

        do
        {
            noinfiniteloop:
            cout << "Here is the Current Grid :" << endl;
            GridDisplay();
            cout << endl;
            cout << endl;
            cout << "Where would you like to go?" << endl;
            cout << turns+1 << ":" ; cin >> Choice;
            if (Choice<0||Choice>9)
                {
                cout << "Invalid Choice." << endl;
                goto noinfiniteloop;
                }
        }
        while (Choice<0||Choice>9);
    }
    while (GridLookup(Choice,Symbol)==false);
}

bool GridLookup(int KeypadNumber,char PlayerSymbol) //Given a keystroke, this function finds the desired location.
{
    int x,y;

    x=(abs(KeypadNumber-9)/3);
    y=(KeypadNumber-1)%3;

    bool squarecheck=SquareOpen(x,y);

    if (!squarecheck)
    {
        cout << "That square is taken." << endl;
        return false;
    }
    else
    {
        Grid[x][y]=PlayerSymbol;
        return true;
    }
}

int PlayerWinPossibilities(int x)//The possible win scenarios for both players depending which integer is passed to the function.
{
    char Symbol;
    if (x==1)
        Symbol='X';
    else
        Symbol='O';

    if (Grid[0][0]==Symbol&&Grid[0][1]==Symbol&&Grid[0][2]==Symbol)
        win=x;
    else if (Grid[1][0]==Symbol&&Grid[1][1]==Symbol&&Grid[1][2]==Symbol)
        win=x;
    else if (Grid[2][0]==Symbol&&Grid[2][1]==Symbol&&Grid[2][2]==Symbol)
        win=x;
    else if (Grid[0][0]==Symbol&&Grid[1][0]==Symbol&&Grid[2][0]==Symbol)
        win=x;
    else if (Grid[0][1]==Symbol&&Grid[1][1]==Symbol&&Grid[2][1]==Symbol)
        win=x;
    else if (Grid[0][2]==Symbol&&Grid[1][2]==Symbol&&Grid[2][2]==Symbol)
        win=x;
    else if (Grid[0][0]==Symbol&&Grid[1][1]==Symbol&&Grid[2][2]==Symbol)
        win=x;
    else if (Grid[2][0]==Symbol&&Grid[1][1]==Symbol&&Grid[0][2]==Symbol)
        win=x;
    else
        return 0;
}

int TiePossibility()//When should a tie be made.
{
    if (turns==8&&(win!=1||win!=2))
        win=3;
    else
        return 0;
}

bool Winner(int win)//Declares what to do should a person win.
{
    switch (win)
    {
        case 1:
            GridDisplay();
            cout << PlayerOne << " wins!" << endl;
            return true;
        case 2:
            GridDisplay();
            cout << PlayerTwo << " wins!" << endl;
            return true;
        case 3:
            GridDisplay();
            cout << "Tie!" << endl;
            return true;
        default:
            cout << "Next round." << endl;
            return false;
    }
}

void TurnCycle()//Holds the sequences which the program will run until the game is won.
{
    bool GameOver=false;

    while(GameOver==false)
    {
        PlayerTurn();
        PlayerWinPossibilities(1);
        PlayerWinPossibilities(2);
        TiePossibility();
        turns = turns+1;
        GameOver = Winner(win);
        if (GameOver==true)
            break;
    }
}

int main()
{
    char exit,answer;
    do
    {
        Introduction();//Function that introduces them to the game.
        PlayerOne = PlayerNames(1);//Function that asks for Player One's name, and stores it to memory.
        PlayerTwo = PlayerNames(2);//Function that asks for Player Two's name, and stores it to memory.
        //PlayerOne = "John";//Temporary Code to shorten testing time.
        //PlayerTwo = "Bryan";//Temporary Code to shorten testing time.

        TurnCycle();
        cout << "Would you like to play again?"<<endl;
        cout << "(Y)es, (N)o" << endl;
        cin >> answer;
        if (answer=='Y'||answer=='y')
        {
            for (int x=0;x<3;x++)
                {
                    for (int y=0;y<3;y++)
                    {
                        Grid[x][y]=' ';
                    }
                }
            turns=0;
			win=0;
        }
    }
    while (answer=='y'||answer=='Y');
    cout << "Thank you for playing." << endl;//Thanks the player for playing.
    cout << "Press x (or any other letter), then enter, to exit." << endl;
    cin >> exit;
    return 0;
}
